
#include "usart_645.h"
#include "los_interrupt.h"

usart1_rx_buf_t usart1_rx_buf;
usart1_tx_buf_t usart1_tx_buf;
bool usart1_receiving = false;

uint8_t checkCnt = 0;

void USART1_IRQHandler(void) 
{
    // 检查接收错误标志
    if(usart_flag_get(USART1, USART_ROERR_FLAG) != RESET) {
        usart_flag_clear(USART1, USART_ROERR_FLAG);
        usart1_clear_rx_buffer();
        return;
    }

    /* 发送中断处理 */
    if (usart_flag_get(USART1, USART_TDBE_FLAG) != RESET) {
        if (usart1_tx_buf.count > 0) {
            uint8_t data_to_send = usart1_tx_buf.buf[usart1_tx_buf.tail];
            usart_data_transmit(USART1, data_to_send);
            // 更新缓冲区索引和计数
            usart1_tx_buf.tail = (usart1_tx_buf.tail + 1) % USART1_TX_BUF_SIZE;
            usart1_tx_buf.count--;
            checkCnt = 0;
        } else {
            // 发送完成
            if(checkCnt++ >= 5)
            {
                usart1_switch_to_receive();
                checkCnt = 0;
            }
        }
    }

    /* 接收中断处理 */
    if (usart_flag_get(USART1, USART_RDBF_FLAG) != RESET) {
        // 读取接收到的数据
        uint8_t data = usart_data_receive(USART1);
        // 检查缓冲区是否已满
        if (usart1_rx_buf.count < USART1_RX_BUF_SIZE) {
            usart1_rx_buf.buf[usart1_rx_buf.head++] = data;
            if (usart1_rx_buf.head >= USART1_RX_BUF_SIZE) {
                usart1_rx_buf.head = 0;
            }
            usart1_rx_buf.count++;
        }
    }
}



void usart1_645_init(uint32_t baudrate)
{
    printf("[USART1] Starting USART1 initialization...(for DL645)\n");
    printf("[USART1] Disabling USART1...\r\n");
    usart_enable(USART1, FALSE);
    // 1. 启用复用时钟和配置映射
    gpio_pin_remap_config(USART1_MUX, TRUE);

    // 初始化GPIO结构体
    gpio_init_type gpio_init_struct;
    gpio_default_para_init(&gpio_init_struct);

    // 使能GPIOB和USART1时钟
    crm_periph_clock_enable(CRM_GPIOB_PERIPH_CLOCK, TRUE);
    crm_periph_clock_enable(CRM_USART1_PERIPH_CLOCK, TRUE);

    // 初始化USART1的TX引脚 (PB6)
    gpio_init_struct.gpio_drive_strength = GPIO_DRIVE_STRENGTH_MODERATE;
    gpio_init_struct.gpio_out_type = GPIO_OUTPUT_PUSH_PULL;
    gpio_init_struct.gpio_mode = GPIO_MODE_MUX;      // 复用推挽输出（符合手册要求）
    gpio_init_struct.gpio_pins = GPIO_PINS_6;
    gpio_init_struct.gpio_pull = GPIO_PULL_UP;
    gpio_init(GPIOB, &gpio_init_struct);

    // 初始化USART1的RX引脚 (PB7)
    gpio_init_struct.gpio_drive_strength = GPIO_DRIVE_STRENGTH_MODERATE;
    gpio_init_struct.gpio_mode = GPIO_MODE_INPUT;    // 必须为输入模式
    gpio_init_struct.gpio_out_type = GPIO_OUTPUT_PUSH_PULL; // 对输入无效但保留
    gpio_init_struct.gpio_pins = GPIO_PINS_7;
    gpio_init_struct.gpio_pull = GPIO_PULL_UP;       // 上拉输入
    gpio_init(GPIOB, &gpio_init_struct);

    usart_transmitter_enable(USART1, TRUE);// 使能USART1的发送器
    usart_receiver_enable(USART1, TRUE);// 使能USART1的接收器  

    UINT32 ret = LOS_HwiCreate(USART1_IRQn, 5, 0, USART1_IRQHandler, 0);//把中断号USART1_IRQn注册到系统中
    if (ret != LOS_OK)
        printf("USART1 LOS_HwiCreate fail, errno:0x%X\n", ret);
    nvic_irq_enable(USART1_IRQn, 5, 0); // 使能USART1的中断，优先级5，子优先级0

    printf("[USART1] Setting communication parameters...\n");
    printf("[USART1] Baudrate: %lu, Data: 9 bits, Parity: Even, Stop: 1 bit\n", baudrate);
    usart_parity_selection_config(USART1, USART_PARITY_EVEN);// 配置USART1的奇偶校验为偶校验
    printf("[USART1] Initializing USART1\n");
    usart_init(USART1, baudrate, USART_DATA_9BITS, USART_STOP_1_BIT);// 初始化USART1
    usart_hardware_flow_control_set(USART1, USART_HARDWARE_FLOW_NONE);

    // 初始化接收缓冲区
    usart1_rx_buf.head = 0;
    usart1_rx_buf.tail = 0;
    usart1_rx_buf.count = 0;

    // 初始化发送缓冲区
    usart1_tx_buf.head = 0;
    usart1_tx_buf.tail = 0;
    usart1_tx_buf.count = 0;

    printf("[USART1] Enabling USART1...\r\n");
    usart_enable(USART1, TRUE);// 使能USART1

    // 默认设置为接收模式
    usart1_switch_to_receive();
    printf("[USART1] USART1 initialization completed successfully\r\n");
}

/* 中断发送 */
void usart1_send_data_it(uint8_t *data, uint16_t len) 
{
    UINT32 intSave;

    // 将数据存入发送缓冲区
    for (uint16_t i = 0; i < len; i++) {
//        while (usart1_tx_buf.count >= USART1_TX_BUF_SIZE); // 等待缓冲区空间
        // 等待缓冲区空间（避免忙等待，可加超时机制）
        while (1) {
            intSave = LOS_IntLock();  // 关中断
            bool is_full = (usart1_tx_buf.count >= USART1_TX_BUF_SIZE);
            LOS_IntRestore(intSave);  // 开中断
            if (!is_full) break;
            LOS_TaskDelay(1); // 非阻塞等待，让出CPU
        }

        intSave = LOS_IntLock();  // 关中断
        usart1_tx_buf.buf[usart1_tx_buf.head] = data[i];
        usart1_tx_buf.head = (usart1_tx_buf.head + 1) % USART1_TX_BUF_SIZE;
        usart1_tx_buf.count++;
        LOS_IntRestore(intSave);  // 开中断
    }

    // 切换到发送模式
    usart1_switch_to_send();
}

/* 切换到接收模式 */
void usart1_switch_to_receive(void) {
    // 禁用发送中断
    usart_interrupt_enable(USART1, USART_TDBE_INT, FALSE);
    
    // 使能接收中断
    usart_interrupt_enable(USART1, USART_RDBF_INT, TRUE);
    
    usart1_receiving = true;
}

/* 切换到发送模式 */
void usart1_switch_to_send(void) {
    // 禁用接收中断
    usart_interrupt_enable(USART1, USART_RDBF_INT, FALSE);
    
    // 使能发送中断
    usart_interrupt_enable(USART1, USART_TDBE_INT, TRUE);
    
    usart1_receiving = false;
}

/* 获取接收到的数据长度 */
uint16_t usart1_get_rx_data_len(void) 
{
    return usart1_rx_buf.count;
}

/* 读取接收缓冲区数据 */
uint16_t usart1_read_rx_data(uint8_t *buf, uint16_t len)
{
    uint16_t i = 0;
    while (usart1_rx_buf.count > 0 && i < len) {
        buf[i++] = usart1_rx_buf.buf[usart1_rx_buf.tail++];
        if (usart1_rx_buf.tail >= USART1_RX_BUF_SIZE) {
            usart1_rx_buf.tail = 0;
        }
        usart1_rx_buf.count--;
    }
    return i;
}

/* 清空接收缓冲区 */
void usart1_clear_rx_buffer(void)
{
    usart1_rx_buf.head = 0;
    usart1_rx_buf.tail = 0;
    usart1_rx_buf.count = 0;
}

/* 测试函数，将接收到的数据发出去 */
void usart1_echo_handler(void)
{
    static uint8_t rx_buffer[USART1_RX_BUF_SIZE];
    uint16_t len = usart1_get_rx_data_len();
    
    if(len > 0)
    {
        // 读取接收到的数据
        uint16_t read_len = usart1_read_rx_data(rx_buffer, len);
        
        #if ECHO_ENABLED
        // 将接收到的数据发送回去
        usart1_send_data_it(rx_buffer, read_len);
        #endif
        
        // 可以在这里添加数据处理逻辑
        // process_received_data(rx_buffer, read_len);
    }
}
